<template>
  <div class="app-container">
    <div class="mx-auto">
      <!-- 头部导航栏 -->
      <div
        class="absolute top-0 left-0 right-0 h-50px bg-white border-bottom z-10 flex items-center px-20px"
      >
        <!-- 左侧标题 -->
        <div class="w-200px flex items-center overflow-hidden">
          <el-button type="primary" icon="ArrowLeftBold" @click="handleBack">退出</el-button>
          <span class="ml-10px text-16px truncate" :title="formData.name || '创建流程'">
            {{ formData.name || '创建流程' }}
          </span>
        </div>

        <!-- 步骤条 -->
        <div class="flex-1 flex items-center justify-center h-full">
          <div class="w-400px flex items-center justify-between h-full">
            <div
              v-for="(step, index) in steps"
              :key="index"
              class="flex items-center cursor-pointer mx-15px relative h-full"
              :class="[
                currentStep === index
                  ? 'text-[#3473ff] border-[#3473ff] border-b-2 border-b-solid'
                  : 'text-gray-500'
              ]"
              @click="handleStepClick(index)"
            >
              <div
                class="w-28px h-28px rounded-full flex items-center justify-center mr-8px border-2 border-solid text-15px"
                :class="[
                  currentStep === index
                    ? 'bg-[#3473ff] text-white border-[#3473ff]'
                    : 'border-gray-300 bg-white text-gray-500'
                ]"
              >
                {{ index + 1 }}
              </div>
              <span class="text-16px font-bold whitespace-nowrap">{{ step.title }}</span>
            </div>
          </div>
        </div>

        <!-- 右侧按钮 -->
        <div class="w-200px flex items-center justify-end gap-2">
          <el-button v-if="actionType === 'update'" type="success" @click="handleDeploy">
            发 布
          </el-button>
          <el-button type="primary" @click="handleSave">
            <span v-if="actionType === 'definition'">恢 复</span>
            <span v-else>保 存</span>
          </el-button>
        </div>
      </div>

      <!-- 主体内容 -->
      <div class="mt-50px">
        <!-- 第一步：基本信息 -->
        <div v-if="currentStep === 0" class="mx-auto w-560px">
          <BasicInfo
            v-model="formData"
            :categoryList="categoryList"
            :userList="userList"
            :deptList="deptList"
            ref="basicInfoRef"
          />
        </div>

        <!-- 第二步：表单设置，传递表单List -->
        <div v-if="currentStep === 1" class="mx-auto w-560px">
          <FormSetting v-model="formData" :formList="formList" ref="formDesignRef" />
        </div>

        <!-- 第三步：流程设计 -->
        <ProcessDesign v-if="currentStep === 2" v-model="formData" ref="processDesignRef" />

        <!-- 第四步：更多设置 ，使用v-model可以在子组件里面设置formData的数据，子组件需要有const modelData = defineModel<any>()；:modelFormId传递给子组件，子组件用props接收-->
        <div v-show="currentStep === 3" class="mx-auto w-700px">
          <ExtraSettings
            ref="extraSettingsRef"   
            
            v-model="formData" 
            :modelFormId="formData.formId"/>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { useRoute, useRouter } from 'vue-router'
import  useTagsViewStore  from '@/store/tagsViewStore.ts'

import {API_BPMN_MODEL,UserSimpleVO,DeptSimpleVO} from '@/api/workflow/bpmnModel.ts'
import {API_BPMN_FORM,BpmnForm} from '@/api/workflow/bpmnForm.ts'
import { API_BPMN_CATEGORY, BpmnCategory } from '@/api/workflow/bpmnCategory.ts'

import {API_BPMN_PROCESS_DEFINITION} from '@/api/workflow/bpmnDefinition.ts'
import { BpmnModelTypeEnum, BpmnModelFormTypeEnum, BpmnUserTaskDuplicateApproveTypeEnum } from '@/utils/constants.ts'
import BasicInfo from './BasicInfo.vue'
import FormSetting from './FormSetting.vue'
import ProcessDesign from './ProcessDesign.vue'
import ExtraSettings from './ExtraSettings.vue'

import useBpmnEnumStore from '@/store/bpmnStore'
const bpmnStore = useBpmnEnumStore()

import { usePlugins } from '@/plugins'
const plugins = usePlugins()
const router = useRouter()

const tagsViewStore = useTagsViewStore() // 视图操作
const route = useRoute()


// 组件引用
const basicInfoRef = ref()
const formDesignRef = ref()
const processDesignRef = ref()
const extraSettingsRef = ref()

/** 步骤校验函数 */
const validateBasic = async () => {
  await basicInfoRef.value?.validate()
}

/** 表单设计校验 */
const validateForm = async () => {
  await formDesignRef.value?.validate()
}

/** 流程设计校验 */
const validateProcess = async () => {
  await processDesignRef.value?.validate()
}

const currentStep = ref(-1) // 步骤控制。-1 用于，一开始全部不展示等当前页面数据初始化完成

const steps = [
  { title: '基本信息', validator: validateBasic },
  { title: '表单设计', validator: validateForm },
  { title: '流程设计', validator: validateProcess },
  { title: '更多设置', validator: null }
]

// 表单数据
const formData: any = ref({
  id: undefined,
  modelId:'',
  name: '',
  key: '',
  category: undefined,
  icon: undefined,
  description: '',
  modelType: BpmnModelTypeEnum.BPMN,
  formType: BpmnModelFormTypeEnum.NORMAL,
  formId: null,
  formCustomCreatePath: '',
  formCustomViewPath: '',
  visible: true,
  startUserType: undefined,
  startUserIdList: [],
  startDeptIdList: [],
  managerUserIdList: [],
  allowCancelRunningProcess: true,
  processIdRule: {
    enable: false,
    prefix: '',
    infix: '',
    postfix: '',
    length: 5
  },
  autoApprovalType: BpmnUserTaskDuplicateApproveTypeEnum.NONE,
  titleSetting: {
    enable: false,
    title: ''
  },
  summarySetting: {
    enable: false,
    summary: []
  },
  executionListenerArray:[],
  taskListenerArray:[]
})

// 流程数据
const processData = ref<any>()
/**
 * provide的作用
1.​跨层级组件通信​：父组件使用 provide提供数据，任何深度的子孙组件都可以通过 inject来注入这些数据。
2.​避免 prop 逐层传递​：解决 prop 需要层层传递的麻烦，尤其是在深层嵌套组件中。
3.​共享公共逻辑或配置​：例如主题、国际化、全局配置等。
 */
provide('processData', processData)
provide('modelData', formData)

// 数据列表
const formList = ref<BpmnForm[]>([])
const categoryList = ref<BpmnCategory[]>([])
const userList = ref<UserSimpleVO[]>([])
const deptList = ref<DeptSimpleVO[]>([])

/** 初始化数据 */
const actionType = route.params.actionType as string //从路由里面获取参数
const initData = async () => {
  if (actionType === 'definition') {
    // 情况一：流程定义场景（恢复）
    const definitionId = route.params.modelId as string //从路由里面获取参数
    //从后端AjaxResult也就是前端的ApiResponse获取
    const {data:data} = await API_BPMN_PROCESS_DEFINITION.getProcessDefinition(definitionId)
    // 将 后端的bpmnDefinition =>赋值给formData也就是 model模型
    formData.value = data
    //多人员发起就是1指定人员,否则就是2指定部门，最后就是0全员
    formData.value.startUserType =
      formData.value.startUserIds?.length > 0 ? 1 : formData.value?.startDeptIds?.length > 0 ? 2 : 0
  } else if (['update', 'copy'].includes(actionType)) {
    // 情况二：修改场景/复制场景
    const modelId = route.params.modelId as string
    formData.value = await API_BPMN_MODEL.getModel(modelId)
    formData.value.startUserType =
      formData.value.startUserIds?.length > 0 ? 1 : formData.value?.startDeptIds?.length > 0 ? 2 : 0

    // 特殊：复制场景，需要删除ID和模型ID，否则就会覆盖旧的
    if (route.params.type === 'copy') {
      delete formData.value.id
      delete formData.modelId
      if (formData.value.bpmnXml) {
        formData.value.bpmnXml = formData.value.bpmnXml.replaceAll(
          formData.value.name,
          formData.value.name + '副本'
        )
        formData.value.bpmnXml = formData.value.bpmnXml.replaceAll(
          formData.value.key,
          formData.value.key + '_copy'
        )
      }
      formData.value.name += '副本'
      formData.value.key += '_copy'
      
      tagsViewStore.setTitle('复制模型')
    }
  } else {
    // 情况三：新增场景
    formData.value.startUserType = 0 // 全体
    formData.value.managerUserIdList.push(1)//超级管理员userId是1
  }

  // 获取表单列表
  formList.value = (await API_BPMN_FORM.getFormSimpleList()).data
  // 获取分类列表
  categoryList.value = (await API_BPMN_CATEGORY.getCategoryAllList()).data
  // 获取用户列表
  userList.value = (await API_BPMN_MODEL.getUserSimpleList()).data
  // 获取部门列表
  deptList.value = (await API_BPMN_MODEL.getDeptSimpleList()).data

  // 最终，设置 currentStep 切换到第一步
  currentStep.value = 0

  // 兼容，以前未配置更多设置的流程
  extraSettingsRef.value.initData()
}

onBeforeMount(

//如果不加 await，那么 bpmnStore.init()会立即返回一个 Promise，而不会等待初始化完成。
//这意味着在 init()方法执行完成之前，代码会继续执行。在 Vue 的生命周期钩子中，这可能导致在初始化完成之前，组件已经继续执行后续操作（比如渲染模板），而此时 store 中的数据可能还没有准备好。
  async () => {
  if(!bpmnStore.isInitialized){
    
    await bpmnStore.init();
  }
  console.log('初始化设计器类型和表单类型选项')
})

/** 根据类型切换流程数据 */
watch(
  async () => formData.value.modelType,// 监听源
  () => { //// 回调函数
    if (formData.value.modelType === BpmnModelTypeEnum.BPMN) {
      processData.value = formData.value.bpmnXml
    } else if (formData.value.modelType === BpmnModelTypeEnum.SIMPLE) {
      processData.value = formData.value.simpleModel
    }
    //console.log('加载流程数据', processData.value)
  },
  {
    immediate: true //这个选项表示在 watch 被创建时立即执行一次回调函数。这样可以在初始化时就根据 formData.value.modelType的初始值设置 processData.value
  }
)

/** 校验所有步骤数据是否完整 */
const validateAllSteps = async () => {
  try {
    // 基本信息校验
    try {
      await validateBasic()
    } catch (error) {
      currentStep.value = 0
      throw new Error('请完善基本信息')
    }

    // 表单设计校验
    try {
      await validateForm()
    } catch (error) {
      currentStep.value = 1
      throw new Error('请完善自定义表单信息')
    }

    // 流程设计校验

    try {
      await validateProcess()
    } catch (error) {
      currentStep.value = 2
      throw new Error('请设计流程')
    }

    return true
  } catch (error) {
    throw error
  }
}

/** 保存操作 */
const handleSave = async () => {
  try {
    // 保存前校验所有步骤的数据
    await validateAllSteps()

    // 更新表单数据
    const modelData = {
      ...formData.value
    }

    if (actionType === 'definition') {
      // 情况一：流程定义场景（恢复）
      await API_BPMN_MODEL.updateModel(modelData)
      // 提示成功
      plugins.$modal.msgSuccess('模型数据恢复至未修改状态成功')
    } else if (actionType === 'update') {
      // 修改场景
      await API_BPMN_MODEL.updateModel(modelData)
      // 提示成功
      plugins.$modal.msgSuccess('模型数据修改成功')
    } else if (actionType === 'copy') {
      // 情况三：复制场景
      formData.value.id = await API_BPMN_MODEL.createModel(modelData)
      // 提示成功
      plugins.$modal.msgSuccess('模型数据复制成功，请修改')
    } else {
      // 情况四：新增场景
      formData.value.id = await API_BPMN_MODEL.createModel(modelData)
      // 提示成功
      plugins.$modal.msgSuccess('新建成功，可点击【发布】按钮，进行发布模型')
    }

    // 返回列表页（排除更新的情况）
    if (actionType !== 'update') {
      await router.push({ name: 'Model' })
    }
  } catch (error: any) {
    //console.error('保存失败:', error)
    plugins.$modal.msgWarning(error.message || '请完善所有步骤的必填信息')
  }
}

/** 发布操作 */
const handleDeploy = async () => {
  try {
    // 修改场景下直接发布，新增场景下需要先确认
    if (!formData.value.id) {
      await plugins.$modal.confirm('是否确认发布该流程？')
    }
    // 校验所有步骤
    await validateAllSteps()

    // 更新表单数据
    const modelData = {
      ...formData.value
    }

    // 先保存所有数据
    if (formData.value.id) {
      await API_BPMN_MODEL.updateModel(modelData)
    } else {
      const result = (await API_BPMN_MODEL.createModel(modelData)).data
      formData.value.id = result
    }

    // 发布
    await API_BPMN_MODEL.deployModel(formData.value.id)
    plugins.$modal.msgSuccess('发布成功')
    // 返回列表页
    await router.push({ name: 'BpmModel' })
  } catch (error: any) {
    console.error('发布失败:', error)
    plugins.$modal.msgWarning(error.message || '发布失败')
  }
}

/** 步骤切换处理 */
const handleStepClick = async (index: number) => {
  try {
    if (index !== 0) {
      await validateBasic()
    }
    if (index !== 1) {
      await validateForm()
    }
    if (index !== 2) {
      await validateProcess()
    }

    // 切换步骤
    currentStep.value = index

    // 如果切换到流程设计步骤，等待组件渲染完成后刷新设计器
    if (index === 2) {
      await nextTick()
      // 等待更长时间确保组件完全初始化
      await new Promise((resolve) => setTimeout(resolve, 200))
      if (processDesignRef.value?.refresh) {
        await processDesignRef.value.refresh()
      }
    }
  } catch (error) {
    console.error('步骤切换失败:', error)
    plugins.$modal.msgWarning('请先完善当前步骤必填信息')
  }
}

/** 返回列表页 */
const handleBack = () => {
  // 先删除当前页签
  tagsViewStore.delView(unref(router.currentRoute))
  // 跳转到列表页
  router.push({ name: 'Model' })
}

/** 初始化 */
onMounted(async () => {
  await initData()
})

// 添加组件卸载前的清理代码
onBeforeUnmount(() => {
  // 清理所有的引用
  basicInfoRef.value = null
  formDesignRef.value = null
  processDesignRef.value = null
})
</script>

<style lang="scss" scoped>
.border-bottom {
  border-bottom: 1px solid #dcdfe6;
}

.text-primary {
  color: #3473ff;
}

.bg-primary {
  background-color: #3473ff;
}

.border-primary {
  border-color: #3473ff;
}
</style>
